package com.common.base.utils

import android.text.TextUtils
import java.math.BigDecimal
import java.math.RoundingMode
import java.text.DecimalFormat
import java.util.Formatter
import java.util.regex.Pattern


/**
 *
 * 作者：sosou
 *
 * 版本：1.0
 *
 * 创建日期：3/2/2023
 *
 * 描述：计算工具类
 *
 * 修订历史：
 *
 */
object MathUtil {

    /**
     * 没有值时
     */
    private const val NONE_VALUE = -1

    /**
     * 小数点后有两位
     */
    private const val INT_TWO = 2

    /**
     * 不能大于3
     */
    private const val MAX_LENGHT = 3

    /**
     * 计算百分比
     */
    fun getPercent(x: Int, total: Int, formatStr: String?): String? {
        return getPercent(x.toLong(), total.toLong(), formatStr)
    }

    fun getPercent(x: Long, total: Long, formatStr: String?): String? {
        var result = "" //接受百分比的值
        val tempresult = x.toDouble() / total.toDouble()
        val df1 = DecimalFormat(formatStr)
        result = df1.format(tempresult)
        return result
    }

    /**
     * 判断是不是偶数
     *
     * @param num
     * @return
     */
    fun isJO(num: Int): Boolean {
        val a = num % 2
        return a == 0
    }

    /**
     * 计算比例
     */
    fun getScale(x: Int, total: Int): Double {
        return getScale(x.toLong(), total.toLong())
    }

    fun getScale(x: Long, total: Long): Double {
//		String result="";//接受百分比的值
//		double tempresult=(double)x/(double)total;
//		DecimalFormat df1 = new DecimalFormat(formatStr);
//		result= df1.format(tempresult);
//		return result;
        return x.toDouble() / total.toDouble()
    }

    /**
     * 按比例缩放x并转为int返回
     */
    fun countSizeByScale2Int(x: Double, scale: Double): Int {
        return countSizeByScale(x, scale).toInt()
    }

    fun countSizeByScale(x: Double, scale: Double): Double {
        return x * scale
    }

    //两差绝对值
    fun getAbs(a: Double, b: Double): Double {
        return Math.abs(sub(a, b))
    }

    // 默认除法运算精度
    private const val DEF_DIV_SCALE = 2

    /**
     * 提供精确减法运算的sub方法
     *
     * @param value1 被减数
     * @param value2 减数
     * @return 两个参数的差
     */
    fun sub(value1: String?, value2: String?): Double {
        if (TextUtils.isEmpty(value1) || TextUtils.isEmpty(value2)) {
            return 0.00
        }
        val b1 = BigDecimal(value1)
        val b2 = BigDecimal(value2)
        return b1.subtract(b2).toDouble()
    }

    /**
     * 提供精确的减法运算。
     *
     * @param value1 被减数
     * @param value2 减数
     * @return 两个参数的差
     */
    fun sub(value1: Number, value2: Number): Double {
        val b1 = BigDecimal(value1.toString())
        val b2 = BigDecimal(value2.toString())
        return b1.subtract(b2).toDouble()
    }

    /**
     * 提供精确的减法运算。
     *
     * @param value1 被减数
     * @param value2 减数
     * @return 两个参数的差
     */
    fun subString(value1: Number, value2: Number): String? {
        val b1 = BigDecimal(value1.toString())
        val b2 = BigDecimal(value2.toString())
        //        return b1.subtract(b2).toString();
        return b1.subtract(b2).stripTrailingZeros().toPlainString() //让bigdecimal不用科学计数法显示
    }

    /**
     * 提供精确减法运算的sub方法
     *
     * @param value1 被减数
     * @param value2 减数
     * @return 两个参数的差
     */
    fun subString2(value1: String?, value2: String?): String? {
        if (TextUtils.isEmpty(value1) || TextUtils.isEmpty(value2)) {
            return "0.00"
        }
        val b1 = BigDecimal(value1)
        val b2 = BigDecimal(value2)
        return b1.subtract(b2).stripTrailingZeros().toPlainString() //让bigdecimal不用科学计数法显示
    }

    /**
     * 提供精确减法运算的sub方法
     *
     * @param value1 被减数
     * @param value2 减数
     * @return 两个参数的差
     */
    fun subString3(value1: String?, value2: String?): Double {
        if (TextUtils.isEmpty(value1) || TextUtils.isEmpty(value2)) {
            return 0.00
        }
        val b1 = BigDecimal(value1)
        val b2 = BigDecimal(value2)
        return b1.subtract(b2).stripTrailingZeros().toDouble() //让bigdecimal不用科学计数法显示
    }

    /**
     * 提供精确加法计算的add方法
     *
     * @param value1 被加数
     * @param value2 加数
     * @return 两个参数的和
     */
    fun add(value1: String?, value2: String?): Double? {
        if (TextUtils.isEmpty(value1) || TextUtils.isEmpty(value2)) {
            return 0.00
        }
        val b1 = BigDecimal(value1)
        val b2 = BigDecimal(value2)
        return b1.add(b2).toDouble()
    }

    /**
     * 提供精确加法计算的add方法
     *
     * @param value1 被加数
     * @param value2 加数
     * @return 两个参数的和
     */
    fun add(value1: String?, value2: String?, flag: Boolean): String? {
        if (TextUtils.isEmpty(value1) || TextUtils.isEmpty(value2)) {
            return "0.00"
        }
        val b1 = BigDecimal(value1)
        val b2 = BigDecimal(value2)
        //        return b1.add(b2).toString();
        return b1.add(b2).stripTrailingZeros().toPlainString() //让bigdecimal不用科学计数法显示
    }

    /**
     * 提供精确加法计算的add方法
     *
     * @param value1 被加数
     * @param value2 加数
     * @return 两个参数的和
     */
    fun add2(value1: String?, value2: String?): Any {
        if (TextUtils.isEmpty(value1) || TextUtils.isEmpty(value2)) {
            return 0.00
        }
        val b1 = BigDecimal(value1)
        val b2 = BigDecimal(value2)
        return b1.add(b2).stripTrailingZeros().toDouble() //让bigdecimal不用科学计数法显示
    }

    /**
     * 提供精确加法计算的add方法
     *
     * @param value1 被加数
     * @param value2 加数
     * @return 两个参数的和
     */
    fun add(
        value1: String?,
        value2: String?,
        value3: String?,
        value4: String?,
        value5: String?
    ): Double? {
        if (TextUtils.isEmpty(value1) || TextUtils.isEmpty(value2) || TextUtils.isEmpty(value3) || TextUtils.isEmpty(
                value4
            )
        ) {
            return 0.00
        }
        val b1 = BigDecimal(value1)
        val b2 = BigDecimal(value2)
        val b3 = BigDecimal(value3)
        val b4 = BigDecimal(value4)
        val b5 = BigDecimal(value5)
        return b1.add(b2).add(b3).add(b4).add(b5).toDouble()
    }

    /**
     * 提供精确的加法运算。
     *
     * @param value1 被加数
     * @param value2 加数
     * @return 两个参数的和
     */
    fun add(value1: Number, value2: Number): Double? {
        val b1 = BigDecimal(value1.toString())
        val b2 = BigDecimal(value2.toString())
        return b1.add(b2).toDouble()
    }

    /**
     * 提供精确的加法运算。
     *
     * @param value1 被加数
     * @param value2 加数
     * @return 两个参数的和
     */
    fun add2(value1: Number, value2: Number): String? {
        val b1 = BigDecimal(value1.toString())
        val b2 = BigDecimal(value2.toString())
        return b1.add(b2).stripTrailingZeros().toPlainString() //让bigdecimal不用科学计数法显示
    }

    /**
     * 提供精确乘法运算的mul方法
     *
     * @param value1 被乘数
     * @param value2 乘数
     * @return 两个参数的积
     */
    fun mul(value1: String?, value2: String?): Double {
        if (TextUtils.isEmpty(value1) || TextUtils.isEmpty(value1)) {
            return 0.00
        }
        val b1 = BigDecimal(value1)
        val b2 = BigDecimal(value2)
        return b1.multiply(b2).toDouble()
    }

    /**
     * 提供精确乘法运算的mul方法
     *
     * @param value1 被乘数
     * @param value2 乘数
     * @return 两个参数的积
     */
    fun mul(value1: String?, value2: String?, flag: Boolean): String? {
        return if (TextUtils.isEmpty(value1) || TextUtils.isEmpty(value2)) {
            "0.00" //让bigdecimal不用科学计数法显示
        } else {
            val b1 = BigDecimal(value1)
            val b2 = BigDecimal(value2)
            //        return b1.multiply(b2).toString();
            b1.multiply(b2).stripTrailingZeros().toPlainString() //让bigdecimal不用科学计数法显示
        }
    }

    /**
     * 提供精确乘法运算的mul方法
     *
     * @param value1 被乘数
     * @param value2 乘数
     * @return 两个参数的积
     */
    fun mul2(value1: String?, value2: String?): String? {
        if (TextUtils.isEmpty(value1) || TextUtils.isEmpty(value1)) {
            return "0.00"
        }
        val b1 = BigDecimal(value1)
        val b2 = BigDecimal(value2)
        //        return b1.multiply(b2).toString();
        return BigDecimal(b1.multiply(b2).stripTrailingZeros().toPlainString()).setScale(
            2,
            BigDecimal.ROUND_HALF_UP
        ).stripTrailingZeros().toPlainString() //让bigdecimal不用科学计数法显示
    }

    /**
     * 提供精确的乘法运算。
     *
     * @param value1 被乘数
     * @param value2 乘数
     * @return 两个参数的积
     */
    fun mul(value1: Number, value2: Number): Double {
        val b1 = BigDecimal(value1.toString())
        val b2 = BigDecimal(value2.toString())
        return b1.multiply(b2).toDouble()
    }

    /**
     * 提供精确乘法运算的mul方法
     *
     * @param value1 被乘数
     * @param value2 乘数
     * @return 两个参数的积
     */
    fun mul3(value1: String?, value2: String?): String? {
        if (TextUtils.isEmpty(value1) || TextUtils.isEmpty(value1)) {
            return "0.00"
        }
        val b1 = BigDecimal(value1)
        val b2 = BigDecimal(value2)
        return BigDecimal(b1.multiply(b2).stripTrailingZeros().toPlainString()).setScale(
            8,
            BigDecimal.ROUND_HALF_UP
        ).stripTrailingZeros().toPlainString() //让bigdecimal不用科学计数法显示
    }

    /**
     * 提供精确乘法运算的mul方法
     *
     * @param value1 被乘数
     * @param value2 乘数
     * @return 两个参数的积
     */
    fun mul4(value1: String?, value2: String?): Double {
        if (TextUtils.isEmpty(value1) || TextUtils.isEmpty(value1)) {
            return 0.00
        }
        val b1 = BigDecimal(value1)
        val b2 = BigDecimal(value2)
        return BigDecimal(b1.multiply(b2).stripTrailingZeros().toPlainString()).setScale(
            8,
            BigDecimal.ROUND_HALF_UP
        ).stripTrailingZeros().toDouble() //让bigdecimal不用科学计数法显示
    }

    /**
     * 提供精确乘法运算的mul方法
     *
     * @param value1 被乘数
     * @param value2 乘数
     * @return 两个参数的积
     */
    fun mul5(value1: String?, value2: String?): Double {
        if (TextUtils.isEmpty(value1) || TextUtils.isEmpty(value1)) {
            return 0.00
        }
        val b1 = BigDecimal(value1)
        val b2 = BigDecimal(value2)
        return BigDecimal(b1.multiply(b2).stripTrailingZeros().toPlainString()).setScale(
            2,
            BigDecimal.ROUND_HALF_UP
        ).stripTrailingZeros().toDouble() //让bigdecimal不用科学计数法显示
    }
    /**
     * 提供精确乘法运算的mul方法
     *
     * @param value1 被乘数
     * @param value2 乘数
     * @return 两个参数的积
     */
    fun mul6(value1: String?, value2: String?, flag: Boolean): String? {
        return if (TextUtils.isEmpty(value1) || TextUtils.isEmpty(value2)) {
            "0.00" //让bigdecimal不用科学计数法显示
        } else {
            val b1 = BigDecimal(value1)
            val b2 = BigDecimal(value2)
            //        return b1.multiply(b2).toString();
            DecimalFormat("##0.00").format(b1.multiply(b2).setScale(2, RoundingMode.DOWN)) //數據小數點後兩位不進行四捨五入
        }
    }


    /**
     * 提供精确的乘法运算。
     *
     * @param value1 被乘数
     * @param value2 乘数
     * @return 两个参数的积
     */
    fun mulFloat(value1: Number, value2: Number): Float? {
        val b1 = BigDecimal(value1.toString())
        val b2 = BigDecimal(value2.toString())
        return b1.multiply(b2).toFloat()
    }

    /**
     * 提供精确的乘法运算。
     *
     * @param value1 被乘数
     * @param value2 乘数
     * @return 两个参数的积
     */
    fun mulInt(value1: Number, value2: Number): Int {
        val b1 = BigDecimal(value1.toString())
        val b2 = BigDecimal(value2.toString())
        return b1.multiply(b2).toInt()
    }

    /**
     * 提供（相对）精确的除法运算，当发生除不尽的情况时， 精确到小数点以后10位，以后的数字四舍五入。
     *
     * @param dividend 被除数
     * @param divisor  除数
     * @return 两个参数的商
     */
    fun div(dividend: Double, divisor: Double): Double? {
        return div(dividend, divisor, DEF_DIV_SCALE)
    }

    /**
     * 提供精确的除法运算方法div
     *
     * @param value1 被除数
     * @param value2 除数
     * @param scale  精确范围
     * @return 两个参数的商
     * @throws IllegalAccessException
     */
    fun div(value1: String?, value2: String?, scale: Int): Double {
        if (TextUtils.isEmpty(value1) || TextUtils.isEmpty(value1)) {
            return 0.00
        }

        //如果精确范围小于0，抛出异常信息
        if (scale < 0) {
            return 0.00
        }
        val b1 = BigDecimal(value1)
        val b2 = BigDecimal(value2)
        return b1.divide(b2, scale, RoundingMode.DOWN).toDouble()
    }

    /**
     * 提供精确的除法运算。当发生除不尽的情况时，由scale参数指定精度，以后的数字四舍五入
     *
     * @param v1    被除数
     * @param v2    除数
     * @param scale 表示表示需要精确到小数点以后几位。
     * @return 两个参数的商
     */
    fun divInt(v1: Double, v2: Double): Int {
        val b1 = BigDecimal(v1)
        val b2 = BigDecimal(v2)
        return if (v2 == 0.0) 0 else b1.divide(b2, 0, RoundingMode.DOWN).toInt()
    }

    /**
     * 提供（相对）精确的除法运算。 当发生除不尽的情况时，由scale参数指定精度，以后的数字四舍五入。
     *
     * @param dividend 被除数
     * @param divisor  除数
     * @param scale    表示表示需要精确到小数点以后几位。
     * @return 两个参数的商
     */
    fun div(dividend: Double, divisor: Double, scale: Int): Double {
        require(scale >= 0) { "保留的小数位数必须大于零" }
        if (dividend == 0.0 || divisor == 0.0) {
            return 0.0
        }
        val b1 = BigDecimal(dividend)
        val b2 = BigDecimal(divisor)
        return b1.divide(b2, scale, RoundingMode.DOWN).toDouble()
    }

    /**
     * 提供（相对）精确的除法运算。 当发生除不尽的情况时，由scale参数指定精度，以后的数字四舍五入。
     *
     * @param dividend 被除数
     * @param divisor  除数
     * @return 两个参数的商
     */
    fun div(dividend: String, divisor: String?, flag: Boolean): String {
        if (TextUtils.isEmpty(dividend) || dividend == "0") {
            return "0.00"
        }
        val b1 = BigDecimal(dividend)
        val b2 = BigDecimal(divisor)
        return try {
            b1.divide(b2, 2, RoundingMode.DOWN).stripTrailingZeros()
                .toPlainString() //让bigdecimal不用科学计数法显示
            // 其他可能抛出ArithmeticException的操作
        } catch (e: ArithmeticException) {
            // 处理异常
            dividend
        }
    }

    /**
     * 提供（相对）精确的除法运算。 当发生除不尽的情况时，由scale参数指定精度，以后的数字四舍五入。
     *
     * @param dividend 被除数
     * @param divisor  除数
     * @return 两个参数的商
     */
    fun div3(dividend: String?, divisor: String?): String {

        if (TextUtils.isEmpty(dividend) || TextUtils.isEmpty(divisor)) {
            return "0.00"
        }
        val b1 = BigDecimal(dividend)
        val b2 = BigDecimal(divisor)
        return if (b1.compareTo(BigDecimal.ZERO) == 0 || b2.compareTo(BigDecimal.ZERO) == 0) {
            "0"
        } else {
            //        return b1.divide(b2, 2, RoundingMode.DOWN).toString();
            b1.divide(b2, 2, RoundingMode.DOWN).stripTrailingZeros()
                .toPlainString() //让bigdecimal不用科学计数法显示
        }
    }

    /**
     * 提供（相对）精确的除法运算。 当发生除不尽的情况时，由scale参数指定精度，以后的数字四舍五入。
     *
     * @param dividend 被除数
     * @param divisor  除数
     * @return 两个参数的商
     */
    fun div4(dividend: String?, divisor: String?, flag: Boolean): String? {
        if (TextUtils.isEmpty(dividend) || TextUtils.isEmpty(divisor)) {
            return "0.00"
        }
        val b1 = BigDecimal(dividend)
        val b2 = BigDecimal(divisor)
        return if (b1.compareTo(BigDecimal.ZERO) == 0 || b2.compareTo(BigDecimal.ZERO) == 0) {
            "0"
        } else {
            //        return b1.divide(b2, 4, RoundingMode.DOWN).toString();
            b1.divide(b2, 4, RoundingMode.DOWN).stripTrailingZeros()
                .toPlainString() //让bigdecimal不用科学计数法显示
        }
    }

    /**
     * 提供（相对）精确的除法运算。 当发生除不尽的情况时，由scale参数指定精度，以后的数字四舍五入。
     *
     * @param dividend 被除数
     * @param divisor  除数
     * @return 两个参数的商
     */
    fun div5(dividend: String?, divisor: String?): String? {
        if (TextUtils.isEmpty(dividend) || TextUtils.isEmpty(divisor)) {
            return "0.00"
        }
        val b1 = BigDecimal(dividend)
        val b2 = BigDecimal(divisor)
        return if (b1.compareTo(BigDecimal.ZERO) == 0 || b2.compareTo(BigDecimal.ZERO) == 0) {
            "0"
        } else {
            b1.divide(b2, 10, RoundingMode.DOWN).stripTrailingZeros()
                .toPlainString() //让bigdecimal不用科学计数法显示
        }
    }

    /**
     * 提供（相对）精确的除法运算。 当发生除不尽的情况时，由scale参数指定精度，以后的数字四舍五入。
     *
     * @param dividend 被除数
     * @param divisor  除数
     * @return 两个参数的商
     */
    fun div8(dividend: String?, divisor: String?, flag: Boolean): String? {
        if (TextUtils.isEmpty(dividend) || TextUtils.isEmpty(divisor)) {
            return "0.00"
        }
        val b1 = BigDecimal(dividend)
        val b2 = BigDecimal(divisor)
        return if (b1.compareTo(BigDecimal.ZERO) == 0 || b2.compareTo(BigDecimal.ZERO) == 0) {
            "0"
        } else {
            b1.divide(b2, 8, RoundingMode.DOWN).stripTrailingZeros()
                .toPlainString() //让bigdecimal不用科学计数法显示
        }
    }

    /**
     * 提供（相对）精确的除法运算。 当发生除不尽的情况时，由scale参数指定精度，以后的数字四舍五入。
     *
     * @param dividend 被除数
     * @param divisor  除数
     * @return 两个参数的商
     */
    fun div9(dividend: String?, divisor: String?): Double {
        if (TextUtils.isEmpty(dividend) || TextUtils.isEmpty(divisor)) {
            return 0.00
        }

        val b1 = BigDecimal(dividend)
        val b2 = BigDecimal(divisor)
        return if (b1.compareTo(BigDecimal.ZERO) == 0 || b2.compareTo(BigDecimal.ZERO) == 0) {
            0.00
        } else {
            b1.divide(b2, 8, RoundingMode.DOWN).stripTrailingZeros()
                .toDouble() //让bigdecimal不用科学计数法显示
        }
    }

    /**
     * 提供（相对）精确的除法运算。 当发生除不尽的情况时，由scale参数指定精度，以后的数字四舍五入。
     *
     * @param dividend 被除数
     * @param divisor  除数
     * @return 两个参数的商
     */
    fun div10(dividend: String?, divisor: String?): String? {
        if (TextUtils.isEmpty(dividend) || TextUtils.isEmpty(divisor)) {
            return "0.00"
        }
        val b1 = BigDecimal(dividend)
        val b2 = BigDecimal(divisor)
        return if (b1.compareTo(BigDecimal.ZERO) == 0 || b2.compareTo(BigDecimal.ZERO) == 0) {
            "0"
        } else {
            BigDecimal(
                b1.divide(b2, 10, RoundingMode.DOWN).stripTrailingZeros().toPlainString()
            ).setScale(8, RoundingMode.DOWN).stripTrailingZeros()
                .toPlainString() //让bigdecimal不用科学计数法显示
        }
    }

    /**
     * 提供精确的除法运算。当发生除不尽的情况时，由scale参数指定精度，以后的数字四舍五入
     *
     * @param v1    被除数
     * @param v2    除数
     * @param scale 表示表示需要精确到小数点以后几位。
     * @return 两个参数的商
     */
    fun div11(v1: Double, v2: Double, scale: Int): Double {
        require(scale >= 0) { "保留的小数位数必须大于零" }
        val b1 = BigDecimal(v1)
        val b2 = BigDecimal(v2)
        return if (v2 == 0.0) 0.00 else b1.divide(b2, scale, RoundingMode.DOWN).toDouble()
    }

    /**
     * 提供精确的小数位四舍五入处理。
     *
     * @param value 需要四舍五入的数字
     * @param scale 小数点后保留几位
     * @return 四舍五入后的结果
     */
    fun round(value: Double?, scale: Int): Double? {
        require(scale >= 0) { "The scale must be a positive integer or zero" }
        val b = BigDecimal(value.toString())
        val one = BigDecimal("1")
        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).toDouble()
    }

    /**
     * 比较大小 浮点数
     *
     * @param val1
     * @param val2
     * @return 0 等于 1>2＝1  1<2=-1
     */
    fun compare(val1: Double?, val2: Double?): Int {
        var result = 0
        val bval1 = BigDecimal(val1!!)
        val bval2 = BigDecimal(val2!!)
        if (bval1.compareTo(bval2) < 0) {
            result = -1 //第一个小于第二个
        }
        if (bval1.compareTo(bval2) == 0) {
            result = 0 //两个相等
        }
        if (bval1.compareTo(bval2) > 0) {
            result = 1 //第一个大于第二个
        }
        return result
    }

    /**
     * 保留两位小数
     *
     * @param value 需要转换的数字
     * @return 正确的值
     */
    fun formatAmount(value: String): String? {
        if (TextUtils.isEmpty(value)) {
            return "0.00"
        }
        val length = value.length
        val digt = value.indexOf(".")

        // 没有小数点
        return if (NONE_VALUE == digt) {
            "$value.00"
        } else if (INT_TWO == length - digt) {
            // 小数点后有一位
            value + "0"
        } else if (NONE_VALUE != digt && MAX_LENGHT < value.length - digt) {
            // 如果字符长度-小数点位置 大于3 则说明小数点后面超过2位数
            value.substring(0, digt + MAX_LENGHT)
        } else {
            // 返回符合要求的数字
            value
        }
    }

    /**
     * 保留两位小数(长度超过两位不截取)
     *
     * @param value 需要转换的数字
     * @return 正确的值
     */
    fun formatAmount2(value: String): String? {
        if (TextUtils.isEmpty(value)) {
            return "0.00"
        }
        val length = value.length
        val digt = value.indexOf(".")

        // 没有小数点
        return if (NONE_VALUE == digt) {
            "$value.00"
        } else if (INT_TWO == length - digt) {
            // 小数点后有一位
            value + "0"
        } else {
            // 返回符合要求的数字
            value
        }
    }

    /**
     * 负数转
     *
     * @param value
     * @return
     */
    fun negative2positive(value: Double): Double {
        var temp = 0.0
        temp = if (value < 0) {
            value * -1
        } else {
            value
        }
        return temp
    }

    /**
     * 判断double是否是整数
     *
     * @param obj
     * @return
     */
    fun isIntegerForDouble(obj: Double): Boolean {
        val eps = 1e-10 // 精度范围
        return obj - Math.floor(obj) < eps
    }

    /**
     * 判断小数位数
     *
     * @param param
     * @return
     */
    fun checkIsDoublePoint(param: Double?): Int {
        if (param == null) {
            return 0
        }
        val bd = BigDecimal(param.toString())
        val ss = bd.stripTrailingZeros().toPlainString().split("\\.".toRegex())
            .dropLastWhile { it.isEmpty() }
            .toTypedArray()
        return if (ss.size <= 1) {
            0
        } else ss[1].length
    }

    /**
     * @param newScale
     * @param param
     * @return
     */
    fun retainDecimals(newScale: Int, param: Double?): String {
        var temp = "0"
        if (param == null) {
            return temp
        }
        val c = BigDecimal(param)
        temp = c.setScale(newScale, BigDecimal.ROUND_DOWN).toDouble().toString()
        return temp
    }

    /**
     * 獲取double數據小數點後兩位不進行四捨五入
     *
     * @param value
     * @return -1 , double
     */
    fun retainDecimals(value: Double): String {
        val bdValue = BigDecimal.valueOf(value)
        //設置小數點後四位
        val money = bdValue.setScale(4, RoundingMode.DOWN).toString() // 保留四位小数，截断非零部分
        val frist = money.substring(0, 1)
        if ("." == frist) {
            return "0" + money.substring(0, 3)
        }
        val index = getIndex(money, '.')
        return if (index == -1) {
            "0.0"
        } else money.substring(0, index + 3)
    }

    /**
     * @param str
     * @param ch
     * @return
     */
    fun getIndex(str: String, ch: Char): Int {
        for (i in 0 until str.length) {
            if (str[i] == '.') {
                return i
            }
        }
        return -1
    }

    /**
     * 獲取double數據小數點後兩位不進行四捨五入
     *
     * @param value
     * @return -1 , double
     */
    fun retainDecimals2(value: Double): Double {
        val temp: Double
        val c = BigDecimal(value)
        temp = c.setScale(2, RoundingMode.DOWN).toDouble()
        return temp
    }

    /**
     * double类型如果小数点后为零则显示整数否则保留两位小数
     *
     * @param value
     * @return
     */
    fun getDoubleValue(value: Double): String {
//        Float f = Float.valueOf(value);
        val mValue: String
        val itemp = Math.round((value - value.toLong()) * 100)
        mValue = if (itemp % 100 == 0L) {
            String.format("%.0f", value)
        } else if (itemp % 10 == 0L) {
            String.format("%.1f", value)
        } else {
            String.format("%.2f", value)
        }
        return mValue
    }

    /**
     * 排除无效小数
     *
     * @param val
     * @return
     */
    fun printNoMoreZero(`val`: Double): String {
        var f = "0"
        val rmZero = Formatter()
        // 进行格式化截断尾部小数并转化成字符串
        val rm = "" + rmZero.format("%g", `val`)
        // 将字符串解析成double并存入大数类
        val todo = BigDecimal.valueOf(rm.toDouble())
        //        // 将数去0输出
//        System.out.println(todo.stripTrailingZeros());
        f = todo.stripTrailingZeros().toPlainString()
        if ("0.0" == f || "0.00" == f) {
            f = "0"
        }
        return f
    }

    /**
     * 格式化
     *
     * @param value
     * @return -1 , double
     */
    fun retainFormatting(value: Double): String? {
        return retainFormatting(value, "##0.00")
    }

    /**
     * 格式化
     *
     * @param value
     * @return -1 , double
     */
    fun retainFormatting(value: Double, pattern: String?): String {
        var pattern = pattern
        if (TextUtils.isEmpty(pattern)) {
            pattern = "##0.00"
        }
        return DecimalFormat(pattern).format(value)
    }

    /**
     * 去掉给定字符串（小数）后面的无效0
     *
     * @param value 小数的字符串表示
     * @return 如果转换失败，返回null
     */
    fun convertByPattern(value: Double): String? {
        val regex = "^(-?\\d*)(\\.?0*)$"
        val matcher = Pattern.compile(regex).matcher(BigDecimal.valueOf(value).toPlainString())
        if (matcher.find()) {
            return matcher.group(1)
        }
        val regex1 = "^(-?\\d*\\.\\d*[1-9])(0*)$"
        val matcher1 = Pattern.compile(regex1).matcher(BigDecimal.valueOf(value).toPlainString())
        return if (matcher1.find()) {
            matcher1.group(1)
        } else BigDecimal.valueOf(value).toPlainString()
    }

    /**
     * 通过将字符串（小数）转换为decimal
     * @param value 小数的字符串表示
     * @return
     */
    fun convertByBigDecimal(value: String?): String? {
        val bigDecimal = BigDecimal(value)
        val bigDecimal1 = bigDecimal.stripTrailingZeros()
        return bigDecimal1.toPlainString()
    }


    /**
     * @param str       字符串只能为两位小数或者整数
     * @param isDecimal 是否是小数
     * @Description 格式化字符串，每三位用逗号隔开
     */
    fun addComma(str: String, isDecimal: Boolean): String {
        //先将字符串颠倒顺序
        var str = str
        str = StringBuilder(str).reverse().toString()
        if (str == "0") {
            return str
        }
        var str2 = ""
        for (i in str.indices) {
            if (i * 3 + 3 > str.length) {
                str2 += str.substring(i * 3, str.length)
                break
            }
            str2 += str.substring(i * 3, i * 3 + 3) + ","
        }
        if (str2.endsWith(",")) {
            str2 = str2.substring(0, str2.length - 1)
        }
        //最后再将顺序反转过来
        val temp = StringBuilder(str2).reverse().toString()
        return if (isDecimal) {
            //去掉最后的","
            temp.substring(0, temp.lastIndexOf(",")) + temp.substring(
                temp.lastIndexOf(",") + 1,
                temp.length
            )
        } else {
            temp
        }
    }

    /**
     * @Description 保持小数点后两位
     */
    fun formatDoublePointTwo(money: Double): String? {
        val formatTemp = DecimalFormat()
        formatTemp.maximumFractionDigits = 2
        formatTemp.groupingSize = 0
        formatTemp.roundingMode = RoundingMode.FLOOR
        return formatTemp.format(money)
    }
    /**
     * 将每三个数字加上逗号处理,最后保留两位小数（通常使用金额方面的编辑）示例：9，702.44
     *
     * @param str
     * @return
     */
    fun addCommaDots(str: String): String? {
        val formatTemp = DecimalFormat()
        formatTemp.applyPattern(",##0.00")
        return formatTemp.format(str.toDouble())
    }

    /**
     * 给数字每三位加一个逗号的处理
     *
     * @param str
     * @return
     */
    fun addComma(str: String): String? {
        val formatTemp = DecimalFormat()
        formatTemp.applyPattern("#,###")
        return formatTemp.format(str.toDouble())
    }


    /**
     * 将每三个数字加上逗号处理,最多保留两位小数（通常使用金额方面的编辑）示例：9，702.44
     *
     * @param text
     * @return
     */
    fun dataFormat(text: String): String? {
        var df: DecimalFormat? = null
        df = if (text.indexOf(".") > 0) { //含有小数
            if (text.length - text.indexOf(".") - 1 == 0) { //含有一位小数
                DecimalFormat("###,##0.")
            } else if (text.length - text.indexOf(".") - 1 == 1) { //含有两位小数
                DecimalFormat("###,##0.0")
            } else { //含有两位以上的小数
                DecimalFormat("###,##0.00")
            }
        } else { //只有整数部分
            DecimalFormat("###,##0")
        }
        var number = 0.0
        number = try {
            text.toDouble()
        } catch (e: Exception) {
            0.0
        }
        return df.format(number)
    }

    /**
     * 判断是否基数
     */
    fun isOdd(num: Int): Boolean {
        return num % 2 == 1
    }

    /**
     * 截取小数
     * @param sourceStr 源字符串
     * @param decimalCount 保留小数位数
     * @return 截取后的字符串
     */
    fun cutDecimals(sourceStr: String, decimalCount: Int): String {
        val index = sourceStr.indexOf(".")
        // 如果没有小数点，原样返回
        if (index == -1) {
            return sourceStr
        }
        // 如果小数位数足够，截取
        if (sourceStr.length - index - 1 >= decimalCount) {
            return sourceStr.substring(0, index + decimalCount + 1)
        }
        // 小数位数不足，补充0
        val result = java.lang.StringBuilder(sourceStr)
        while (result.length - index - 1 < decimalCount) {
            result.append('0')
        }
        return result.toString()
    }
}